using System;
using System.Collections.Generic;
using UnityEngine;

namespace EventBehaviorTree
{
    public class Blackboard
    {
        private Dictionary<string, BBDataBase> _blackboard;

        public Blackboard()
        {
            _blackboard = new Dictionary<string, BBDataBase>();
        }

        public void Reg_Data<BBDataType>(string key, BBDataType value)
        {
            if (_blackboard.ContainsKey(key)) return;
            _blackboard.Add(key, value as BBDataBase);
            //Debug.Log(key);
        }

        public T Get<T>(string key)
        {
            BBDataBase result = _blackboard[key];
            if (result == null) return default;
            return (result as BBData<T>).GetValue();
        }

        public void Set<T>(string key, BBData<T> value)
        {
            if (value == null || value.GetValue() == null) return;
            if (!_blackboard.ContainsKey(key))
            {
                Reg_Data(key, value);
                return;
            }
            BBData<T> EBT_Data = _blackboard[key] as BBData<T>;
            if (EBT_Data == null || EBT_Data.GetValue() == null)
            {
                _blackboard[key] = value;
                return;
            }
            if (!EBT_Data.GetValue().Equals(value.GetValue()))
            {
                //TODO: observe
                EBT_Data.SetValue(value);
            }
        }
        public void Set<T>(string key, T value)
        {
            if (!_blackboard.ContainsKey(key))
            {
                switch (value)
                {
                    case bool formattedValue:
                        Reg_Data(key, new BB_bool(formattedValue));
                        return;
                    case int formattedValue:
                        Reg_Data(key, new BB_int(formattedValue));
                        return;
                    case float formattedValue:
                        Reg_Data(key, new BB_float(formattedValue));
                        return;
                    default:
                        return;
                }
            }
            BBData<T> EBT_Data = _blackboard[key] as BBData<T>;
            if (EBT_Data == null || EBT_Data.GetValue() == null)
            {
                switch (value)
                {
                    case bool formattedValue:
                        _blackboard[key] = new BB_bool(formattedValue);
                        return;
                    case int formattedValue:
                        _blackboard[key] = new BB_int(formattedValue);
                        return;
                    case float formattedValue:
                        _blackboard[key] = new BB_float(formattedValue);
                        return;
                    default:
                        return;
                }
            }
            if (!EBT_Data.GetValue().Equals(value))
            {
                //TODO: observe
                EBT_Data.SetValue(value);
            }
        }
        public bool Compare(string lhsKey, string rhsKey, CmprOP cmprOP)
        {
            Debug.Assert(_blackboard.ContainsKey(lhsKey) && _blackboard.ContainsKey(rhsKey));
            return BlackboardHelper.Compare(_blackboard[lhsKey], _blackboard[rhsKey], cmprOP);
        }
        public bool Compare(string boolKey, CmprOP cmprOP)
        {
            Debug.Assert(_blackboard.ContainsKey(boolKey));
            return BlackboardHelper.Compare(_blackboard[boolKey], cmprOP);
        }
    }
}
